import aiohttp
import asyncio
from datetime import datetime
from typing import List, Dict, Any
from config.kline_settings import API_BASE_URL, API_KLINE_ENDPOINT
from utils.time_utils import TimeRangeHandler
import json
from utils.logger import logger  # 使用全局配置的logger

class KlineDataFetcher:
    def __init__(self):
        self.session = None

    async def init_session(self):
        if not self.session:
            self.session = aiohttp.ClientSession()

    async def close_session(self):
        if self.session:
            await self.session.close()
            self.session = None

    async def fetch_kline_data(
        self,
        symbol: str,
        granularity: str,
        start_time: datetime,
        end_time: datetime
    ) -> List[Dict[str, Any]]:
        """获取K线数据"""
        await self.init_session()
        
        # 转换时间为时间戳
        start_ts = TimeRangeHandler.datetime_to_timestamp(start_time)
        end_ts = TimeRangeHandler.datetime_to_timestamp(end_time)
        
        params = {
            "symbol": symbol,
            "granularity": granularity,
            "startTime": str(start_ts),
            "endTime": str(end_ts),
            "limit": "200",
            "productType": "SUSDT-FUTURES"  # 使用模拟盘
        }

        url = f"{API_BASE_URL}{API_KLINE_ENDPOINT}"
        
        # 记录请求详情
        logger.info(
            "\n=================== K线数据请求 ===================\n"
            f"请求URL: {url}\n"
            f"请求方法: GET\n"
            f"交易对: {symbol}\n"
            f"K线粒度: {granularity}\n"
            f"开始时间: {start_time}\n"
            f"结束时间: {end_time}\n"
            f"请求参数:\n{json.dumps(params, indent=2, ensure_ascii=False)}\n"
            "================================================"
        )
        
        try:
            async with self.session.get(url, params=params) as response:
                response_text = await response.text()
                logger.info(
                    "\n=================== K线数据响应 ===================\n"
                    f"状态码: {response.status}\n"
                    f"响应头:\n{json.dumps(dict(response.headers), indent=2, ensure_ascii=False)}\n"
                    f"响应内容:\n{response_text[:500]}...(已截断)\n"  # 只显示前500个字符
                    "================================================"
                )
                
                if response.status == 200:
                    data = json.loads(response_text)
                    result = data.get("data", [])
                    logger.info(
                        f"\n================= 数据处理结果 ===================\n"
                        f"获取数据条数: {len(result)}\n"
                        f"数据示例(前2条):\n{json.dumps(result[:2], indent=2, ensure_ascii=False) if result else '无数据'}\n"
                        "================================================"
                    )
                    return result
                else:
                    logger.error(
                        f"\n=================== 请求失败 ===================\n"
                        f"状态码: {response.status}\n"
                        f"错误响应:\n{response_text}\n"
                        "================================================"
                    )
                    return []
        except Exception as e:
            logger.error(
                f"\n=================== 请求异常 ===================\n"
                f"异常类型: {type(e).__name__}\n"
                f"错误信息: {str(e)}\n"
                "================================================"
            )
            return []

    async def fetch_all_kline_data(
        self,
        symbol: str,
        granularity: str,
        start_time: datetime,
        end_time: datetime
    ) -> List[Dict[str, Any]]:
        """获取指定时间范围内的所有K线数据"""
        logger.info(
            "\n=================== 开始获取K线数据 ===================\n"
            f"交易对: {symbol}\n"
            f"K线粒度: {granularity}\n"
            f"开始时间: {start_time}\n"
            f"结束时间: {end_time}\n"
            "===================================================="
        )
        
        # 拆分时间范围
        time_ranges = TimeRangeHandler.split_time_range(start_time, end_time, granularity)
        logger.info(
            "\n=================== 时间范围拆分 ===================\n"
            f"总计划请求次数: {len(time_ranges)}\n"
            "拆分详情:\n" + 
            "\n".join([f"  {i+1}. {start} 至 {end} ({(end - start).total_seconds() / 60:.2f}分钟)" 
                      for i, (start, end) in enumerate(time_ranges)]) +
            "\n===================================================="
        )
        
        all_data = []

        # 并发获取所有数据
        tasks = [
            self.fetch_kline_data(symbol, granularity, start, end)
            for start, end in time_ranges
        ]
        results = await asyncio.gather(*tasks)

        # 合并数据
        for data in results:
            all_data.extend(data)

        # 按时间排序
        all_data.sort(key=lambda x: int(x[0]))  # x[0] 是时间戳
        
        # 记录最终结果
        if all_data:
            first_time = datetime.fromtimestamp(int(all_data[0][0])/1000)
            last_time = datetime.fromtimestamp(int(all_data[-1][0])/1000)
            logger.info(
                "\n=================== 数据获取完成 ===================\n"
                f"总获取数据条数: {len(all_data)}\n"
                f"请求时间范围: {start_time} 至 {end_time}\n"
                f"实际数据范围: {first_time} 至 {last_time}\n"
                f"数据示例(前2条):\n{json.dumps(all_data[:2], indent=2, ensure_ascii=False) if all_data else '无数据'}\n"
                "===================================================="
            )
        else:
            logger.warning(
                "\n=================== 数据获取完成 ===================\n"
                "未获取到任何数据\n"
                f"请求时间范围: {start_time} 至 {end_time}\n"
                "===================================================="
            )
        
        return all_data 